{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "54bd32c5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-12-09T06:52:38.038063Z",
     "start_time": "2023-12-09T06:52:37.104554Z"
    },
    "execution": {
     "iopub.execute_input": "2024-04-09T13:55:06.377637Z",
     "iopub.status.busy": "2024-04-09T13:55:06.375485Z",
     "iopub.status.idle": "2024-04-09T13:55:06.387475Z",
     "shell.execute_reply": "2024-04-09T13:55:06.385721Z",
     "shell.execute_reply.started": "2024-04-09T13:55:06.377529Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.fft as fft\n",
    "import cv2\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "from tqdm import tqdm\n",
    "import pandas as pd\n",
    "from cv2 import dct\n",
    "import os\n",
    "import imageio\n",
    "os.environ['KMP_DUPLICATE_LIB_OK']='True'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "2f270776",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-12-09T07:35:19.444806Z",
     "start_time": "2023-12-09T07:35:19.430842Z"
    },
    "execution": {
     "iopub.execute_input": "2024-04-10T01:36:10.235336Z",
     "iopub.status.busy": "2024-04-10T01:36:10.233816Z",
     "iopub.status.idle": "2024-04-10T01:36:10.316561Z",
     "shell.execute_reply": "2024-04-10T01:36:10.315285Z",
     "shell.execute_reply.started": "2024-04-10T01:36:10.235267Z"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "def image_hash(img_path,n,image_block_size):\n",
    "    img = processing(img_path,n,image_block_size)\n",
    "    C_r_list = image_feature(img,image_block_size)\n",
    "    h_i = gen_hashing(C_r_list)\n",
    "    return h_i\n",
    "\n",
    "def processing(img_path,n,image_block_size):\n",
    "    \"\"\"\n",
    "    input：图片的路径\n",
    "    output：处理后的RGB图片\n",
    "    \"\"\"\n",
    "    try:\n",
    "        img = cv2.imread(img_path)\n",
    "        x = img.shape[0]//2 # 高度\n",
    "        y = img.shape[1]//2 # 宽度\n",
    "        Min = x if x<y else y\n",
    "        cropped_image = img[x-Min:x+Min, y-Min:y+Min] # 裁剪图像\n",
    "        img = cv2.resize((img), (512,512), interpolation=cv2.INTER_LINEAR)\n",
    "    except:\n",
    "        img = imageio.mimread(img_path)\n",
    "        img = np.array(img)\n",
    "        img = img[0]\n",
    "        img = img[:, :, 0:3]\n",
    "        x = img.shape[0]//2 # 高度\n",
    "        y = img.shape[1]//2 # 宽度\n",
    "        Min = x if x<y else y\n",
    "        cropped_image = img[x-Min:x+Min, y-Min:y+Min] # 裁剪图像\n",
    "        img = cv2.resize((img), (512,512), interpolation=cv2.INTER_LINEAR)\n",
    "#     out = cv2.GaussianBlur(img, (3, 3),1.3) # 使用python自带的高斯滤波\n",
    "    kernel = np.array([[1,2,1],[2,4,2],[1,2,1]])/16\n",
    "    out = cv2.filter2D(img, -1 , kernel=kernel)  # 二维滤波器\n",
    "    out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)\n",
    "    ring_img = ring_partition(out,n,image_block_size)\n",
    "    return ring_img.transpose(2,1,0)\n",
    "    # return ring_img\n",
    "\n",
    "def ring_partition(img,n,image_block_size):\n",
    "    \"\"\"\n",
    "    使用环形分区形成二次图像\n",
    "    img:原始图片\n",
    "    n:环形分区\n",
    "    return:二次图像\n",
    "    \"\"\"\n",
    "    radius = [0]\n",
    "    u_a = int(np.floor((img.shape[0]/2) ** 2 * np.pi / n)/image_block_size)*image_block_size\n",
    "    radius.append(np.sqrt(u_a / np.pi))\n",
    "    R_result = np.zeros((n,u_a))\n",
    "    G_result = np.zeros((n,u_a))\n",
    "    B_result = np.zeros((n,u_a))\n",
    "    for i in range(1,n):\n",
    "        radius.append(np.sqrt((u_a + np.pi * radius[i] ** 2) / np.pi))\n",
    "    # radius = np.ceil(radius)\n",
    "    for i in range(len(radius)-1):\n",
    "        inner_radius = radius[i]\n",
    "        outer_radius = radius[i+1]\n",
    "        ring_result = ring_value(img,inner_radius,outer_radius,u_a)\n",
    "        R_result[i] = ring_result[0]\n",
    "        G_result[i] = ring_result[1]\n",
    "        B_result[i] = ring_result[2]\n",
    "    return np.array([R_result,G_result,B_result])\n",
    "\n",
    "def ring_value(img,inner_radius,outer_radius,u_a):\n",
    "    \"\"\"\n",
    "    获取环形分区中不为0的值，并且以升序的形式排序\n",
    "    return:(3,448)\n",
    "    \"\"\"\n",
    "    center = (img.shape[0],img.shape[0])\n",
    "    x,y = np.ogrid[0:img.shape[0],0:img.shape[0]]\n",
    "    distance = np.sqrt((x-img.shape[0]/2)**2 + (y-img.shape[0]/2)**2)\n",
    "    mask = (distance < outer_radius) & (distance >=inner_radius)\n",
    "    R = img[mask,0]\n",
    "    G = img[mask,1]\n",
    "    B = img[mask,2]\n",
    "    result = np.zeros((3,u_a))\n",
    "    for index,i in enumerate((R,G,B)):\n",
    "        xp = np.linspace(1, len(i), len(i))  \n",
    "        # 定义要插值的x值\n",
    "        x = np.linspace(1, len(i), u_a)\n",
    "        result[index] = np.sort(np.interp(x, xp, np.sort(i)))\n",
    "    return result\n",
    "\n",
    "def image_feature(img,image_block_size):\n",
    "    \"\"\"\n",
    "    iamge:(512,512,3)\n",
    "    return: array格式(x,64,64)\n",
    "    \"\"\"\n",
    "    C_r_list = np.zeros((0,image_block_size,image_block_size)).tolist()\n",
    "    for i in range(0,img.shape[0],image_block_size):\n",
    "        for j in range(0,img.shape[1],image_block_size):\n",
    "            image_block = img[i:i+image_block_size,j:j+image_block_size,:]\n",
    "            C_r,C_i,C_j,C_k = QDCT(image_block) # 可以在这里取出实部和三个虚数的实部\n",
    "            C_r_list.append(np.sqrt(C_r**2+C_i**2+C_j**2+C_k**2).tolist())\n",
    "            # C_r_list.append(C_r.tolist())\n",
    "    return np.array(C_r_list)\n",
    "\n",
    "def gen_hashing(feature_matrix):\n",
    "    \"\"\"\n",
    "    生成图像哈希值,和原论文不同，我的P和Q矩阵是每一行代表一个图像块。\n",
    "    input:array (x,64,64)\n",
    "    output:list (x)\n",
    "    \"\"\"\n",
    "    print(feature_matrix.shape)\n",
    "    d_i = []\n",
    "    h_i = []\n",
    "    P_matrix = np.zeros((0,32)).tolist()\n",
    "    Q_matrix = np.zeros((0,32)).tolist()\n",
    "    for i in feature_matrix:\n",
    "        i = np.array(i)\n",
    "        row = i[0,1:33].reshape(1,-1)\n",
    "        column = i[1:33,0].reshape(1,-1)\n",
    "        P_matrix.extend(row.tolist())\n",
    "        Q_matrix.extend(column.tolist())\n",
    "    P_matrix = np.array(P_matrix)\n",
    "    Q_matrix = np.array(Q_matrix)\n",
    "    # P_matrix_1 = P_matrix\n",
    "    # Q_matrix_1 = Q_matrix\n",
    "    P_matrix_1 = (P_matrix - np.mean(P_matrix,axis = 0))/np.std(P_matrix,axis = 0,ddof=1) # 将矩阵进行归一化\n",
    "    Q_matrix_1 = (Q_matrix - np.mean(Q_matrix,axis = 0))/np.std(Q_matrix,axis = 0,ddof=1)\n",
    "    d_i = np.sqrt(np.sum((P_matrix_1 - Q_matrix_1)**2,axis = 1)) # 按照行相加\n",
    "    median = np.median(d_i)\n",
    "    for i in d_i:\n",
    "        if i < median:\n",
    "            h_i.append(0)\n",
    "        else:\n",
    "            h_i.append(1)\n",
    "    return np.array(h_i)\n",
    "\n",
    "def QDCT(img):\n",
    "    \"\"\"\n",
    "    img：(64,64,3)\n",
    "    \"\"\"\n",
    "    # 纯四元数版本\n",
    "    C_r = cv2.dct(np.float32(img[:,:,0]+img[:,:,1]+img[:,:,2]) * (- 1 / np.sqrt(3)))\n",
    "    C_i = cv2.dct(np.float32(img[:,:,2]-img[:,:,1]) * (1 / np.sqrt(3)))\n",
    "    C_j = cv2.dct(np.float32(img[:,:,0]-img[:,:,2]) * (1 / np.sqrt(3)))\n",
    "    C_k = cv2.dct(np.float32(img[:,:,1]-img[:,:,0]) * (1 / np.sqrt(3)))\n",
    "    # 四元数版本\n",
    "    # Y = cv2.cvtColor(img.astype('float32'), cv2.COLOR_RGB2YUV)[:,:,0]\n",
    "    # V_blk = np.sum((Y-np.mean(Y))**2)/(img.shape[0]**2)\n",
    "    # C_r = cv2.dct(np.float32(img[:,:,0]+img[:,:,1]+img[:,:,2]) * (- 1 / np.sqrt(3)))\n",
    "    # C_i = cv2.dct(np.float32(img[:,:,2]-img[:,:,1]+V_blk) * (1 / np.sqrt(3)))\n",
    "    # C_j = cv2.dct(np.float32(img[:,:,0]-img[:,:,2]+V_blk) * (1 / np.sqrt(3)))\n",
    "    # C_k = cv2.dct(np.float32(img[:,:,1]-img[:,:,0]+V_blk) * (1 / np.sqrt(3)))\n",
    "    return C_r,C_i,C_j,C_k\n",
    "\n",
    "def dist_img(h1,h2):\n",
    "    return sum(np.abs(h1-h2))\n",
    "\n",
    "def dis_different_dir(path,n,image_block_size,des_path):\n",
    "    # 目录下图片之间的距离\n",
    "    dirs = os.listdir(path)\n",
    "    image_set_list = []\n",
    "    image_hashing_value_set = []\n",
    "    for i in tqdm(dirs,ncols = 50):\n",
    "    # for i in dirs:\n",
    "        image_hashing_value_set.append(image_hash(os.path.join(path, i),n,image_block_size))\n",
    "    for i in range(len(image_hashing_value_set)):\n",
    "        for j in range(i+1,len(image_hashing_value_set)):\n",
    "            image_set_list.append(dist_img(image_hashing_value_set[i],image_hashing_value_set[j]))\n",
    "    for i in range(int(np.ceil(len(image_set_list)/1000000))-1):\n",
    "        start = i*1000000\n",
    "        end = (i+1)*1000000\n",
    "        pd.DataFrame(image_set_list[start:end]).to_excel(os.path.join(des_path,f\"different_image_result_{i+1}.xlsx\"),index = False)\n",
    "    pd.DataFrame(image_set_list[end+1:]).to_excel(os.path.join(des_path,f\"different_image_result_{i+2}.xlsx\"),index = False)\n",
    "    return image_set_list,image_hashing_value_set\n",
    "\n",
    "def dis_similar_dir(path,n,image_block_size):\n",
    "    \"\"\"\n",
    "    path:相同图片每种操作的目录\n",
    "    n:环数\n",
    "    block_size:分区大小\n",
    "    return:所有相同图片哈希距离的列表\n",
    "    \"\"\"\n",
    "    # 计算相同类型图片的距离\n",
    "    dir_rotation = os.listdir(path)\n",
    "    dis_similar = []\n",
    "    for i in dir_rotation:\n",
    "        if (os.path.splitext(i)[1] == \".bmp\") | (os.path.splitext(i)[1] == \".jpg\"):\n",
    "            h1 = image_hash(os.path.join(path, i),n,image_block_size)\n",
    "            dir_temp = os.path.join(path,os.path.splitext(i)[0])\n",
    "            for j in os.listdir(dir_temp):\n",
    "                h2 = image_hash(os.path.join(dir_temp,j),n,image_block_size)\n",
    "                dis_similar.append(dist_img(h1,h2))\n",
    "    return dis_similar\n",
    "\n",
    "def dir_dis_similar_dir(total_path,n,image_block_size,des_path):\n",
    "    \"\"\"\n",
    "    total_path:相同图片各种操作的根目录\n",
    "    des_path:存放结果的目录\n",
    "    return：存放每一种操作相同图片哈希距离的字典\n",
    "    \"\"\"\n",
    "    fold_each_attack = os.listdir(total_path)\n",
    "    dir_each_attack= {}\n",
    "    if not os.path.exists(os.path.join(des_path,\"similar_image_result\")):\n",
    "        os.makedirs(os.path.join(des_path,\"similar_image_result\"))\n",
    "    # total_path = os.path.join(total_path,\"similar_image_result\")\n",
    "    for i in tqdm(fold_each_attack,ncols = 50):\n",
    "        attack_path = os.path.join(total_path,i)\n",
    "        dir_each_attack[i] = dis_similar_dir(attack_path,n,image_block_size)\n",
    "        file_name = i + \".xlsx\"\n",
    "        pd.DataFrame(dir_each_attack[i]).to_excel(os.path.join(des_path,\"similar_image_result\",file_name),index = False)\n",
    "    return dir_each_attack\n",
    "\n",
    "def my_auc(image_similar, image_different):\n",
    "    from scipy import integrate\n",
    "    sum1 = len(image_similar)\n",
    "    sum2 = len(image_different)\n",
    "    tpr = []\n",
    "    fpr = []\n",
    "    threshold_max = (max(max(image_similar), max(image_different)))\n",
    "    for threshold in np.linspace(0,threshold_max,50):\n",
    "        tpr_number = len(image_similar[image_similar <= threshold])\n",
    "        fpr_number = len(image_different[image_different <= threshold])\n",
    "        tpr.append(tpr_number/sum1)\n",
    "        fpr.append(fpr_number/sum2)\n",
    "    return integrate.trapezoid(tpr,fpr)\n",
    "\n",
    "def stat_analysis(result_path):\n",
    "    \"\"\"\n",
    "    result_path:保存结果的路径\n",
    "    \"\"\"\n",
    "    dirs = os.listdir(result_path)\n",
    "    for i in dirs:\n",
    "        file_path = os.path.join(result_path, i)\n",
    "        if os.path.isdir (file_path):\n",
    "            for j in os.listdir(file_path):\n",
    "                xlsx_path = os.path.join(file_path,j)\n",
    "                data = pd.read_excel(xlsx_path,header = 0)[0]\n",
    "                print(f\"{j}的最小值：{min(data)}最大值：{max(data)}平均值：{np.mean(data)}\")\n",
    "        else:\n",
    "            xlsx_path = file_path\n",
    "            data = pd.read_excel(xlsx_path,header = 0)[0]\n",
    "            print(f\"{i}的最小值：{min(data)}最大值：{max(data)}平均值：{np.mean(data)}\")\n",
    "\n",
    "def auc_analysis(dir_path):\n",
    "    \"\"\"\n",
    "    dir_path:保存结果的路径\n",
    "    \"\"\"\n",
    "    similar_image_result_path = os.path.join(dir_path,\"similar_image_result\")\n",
    "    data_different =pd.Series()\n",
    "    for i in os.listdir(dir_path):\n",
    "        if not os.path.isdir(os.path.join(dir_path,i)):\n",
    "            print(os.path.join(dir_path,i))\n",
    "            temp = pd.read_excel(os.path.join(dir_path,i),header = 0)[0]\n",
    "            data_different = pd.concat((data_different,temp),axis=0)\n",
    "    similar_image_result_path_total = pd.Series()\n",
    "    for i in os.listdir(similar_image_result_path):\n",
    "        data_similar = pd.read_excel(os.path.join(similar_image_result_path,i),header = 0)[0]\n",
    "        similar_image_result_path_total= pd.concat((similar_image_result_path_total,data_similar),axis=0)\n",
    "        print(f\"{i}和不同图片的auc值：{my_auc(data_similar,data_different)}\")\n",
    "    print(f\"所有相同图片和不同图片 的auc值：{my_auc(similar_image_result_path_total,data_different)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "ebfec79e-210a-41fa-9334-893652e45164",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-04-10T01:37:03.609318Z",
     "iopub.status.busy": "2024-04-10T01:37:03.607272Z",
     "iopub.status.idle": "2024-04-10T01:37:04.403428Z",
     "shell.execute_reply": "2024-04-10T01:37:04.402857Z",
     "shell.execute_reply.started": "2024-04-10T01:37:03.609248Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(510, 20, 20)\n",
      "(510, 20, 20)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1,\n",
       "       0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0,\n",
       "       0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,\n",
       "       1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1,\n",
       "       1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,\n",
       "       0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,\n",
       "       0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,\n",
       "       1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1,\n",
       "       1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,\n",
       "       1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\n",
       "       0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,\n",
       "       0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0,\n",
       "       1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1,\n",
       "       1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1,\n",
       "       0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1,\n",
       "       1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h1 = image_hash(\"../data/Lenna_(test_image).png\",200,20)\n",
    "h1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "78ad3d8b-4c73-4646-bd05-36507d588579",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-04-09T13:55:08.514818Z",
     "iopub.status.busy": "2024-04-09T13:55:08.513254Z",
     "iopub.status.idle": "2024-04-09T15:16:30.697954Z",
     "shell.execute_reply": "2024-04-09T15:16:30.696816Z",
     "shell.execute_reply.started": "2024-04-09T13:55:08.514745Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████| 3307/3307 [40:23<00:00,  1.36it/s]\n",
      "100%|████████████| 16/16 [33:45<00:00, 126.60s/it]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "./混合攻击结果/纯四元数版本_环形分区结果/different_image_result_1.xlsx\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_188727/1561490936.py:243: FutureWarning: The behavior of array concatenation with empty entries is deprecated. In a future version, this will no longer exclude empty items when determining the result dtype. To retain the old behavior, exclude the empty entries before the concat operation.\n",
      "  data_different = pd.concat((data_different,temp),axis=0)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "./混合攻击结果/纯四元数版本_环形分区结果/different_image_result_2.xlsx\n",
      "./混合攻击结果/纯四元数版本_环形分区结果/different_image_result_3.xlsx\n",
      "./混合攻击结果/纯四元数版本_环形分区结果/different_image_result_4.xlsx\n",
      "./混合攻击结果/纯四元数版本_环形分区结果/different_image_result_5.xlsx\n",
      "./混合攻击结果/纯四元数版本_环形分区结果/different_image_result_6.xlsx\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_188727/1561490936.py:247: FutureWarning: The behavior of array concatenation with empty entries is deprecated. In a future version, this will no longer exclude empty items when determining the result dtype. To retain the old behavior, exclude the empty entries before the concat operation.\n",
      "  similar_image_result_path_total= pd.concat((similar_image_result_path_total,data_similar),axis=0)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "IDR+AWGN+GC.xlsx和不同图片的auc值：0.9413161176606353\n",
      "IDR+AWGN+SN.xlsx和不同图片的auc值：0.9428393445251994\n",
      "IDR+SPN+CA.xlsx和不同图片的auc值：0.9394158520794346\n",
      "IDR+SPN+JC.xlsx和不同图片的auc值：0.9413495892344603\n",
      "IDR+AWGN+GLF.xlsx和不同图片的auc值：0.9430377454318478\n",
      "IDR+SPN+GC.xlsx和不同图片的auc值：0.9413161176606353\n",
      "IDR+SPN+SN.xlsx和不同图片的auc值：0.9417801867567186\n",
      "IDR+AWGN+IS.xlsx和不同图片的auc值：0.9404025212136697\n",
      "IDR+AWGN+BA.xlsx和不同图片的auc值：0.9375519225996545\n",
      "IDR+SPN+GLF.xlsx和不同图片的auc值：0.9430377454318478\n",
      "IDR+AWGN+CA.xlsx和不同图片的auc值：0.9449006854514888\n",
      "IDR+AWGN+JC.xlsx和不同图片的auc值：0.9406390182253508\n",
      "IDR+SPN+BA.xlsx和不同图片的auc值：0.9340135845588349\n",
      "IDR+SPN+IS.xlsx和不同图片的auc值：0.9404025212136697\n",
      "IDR+AWGN+PSNR.xlsx和不同图片的auc值：0.9376675153806808\n",
      "IDR+SPN+PSNR.xlsx和不同图片的auc值：0.9396078845214553\n",
      "所有相同图片和不同图片 的auc值：0.9408613802309674\n"
     ]
    }
   ],
   "source": [
    "dis_different_dir(\"../new_data/different_image/\",200,20,\"./混合攻击结果/纯四元数版本_环形分区结果\")\n",
    "dir_dis_similar_dir(\"../new_data/multiple_attack_2/\",200,20,\"./混合攻击结果/纯四元数版本_环形分区结果\")\n",
    "# stat_analysis(\"./新数据集结果/纯四元数版本_环形分区_(200,20)结果/\")\n",
    "auc_analysis(\"./混合攻击结果/纯四元数版本_环形分区结果\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1bb1633b-7368-40ec-9322-5923e4e32487",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-01-27T09:59:11.518770Z",
     "iopub.status.busy": "2024-01-27T09:59:11.518770Z",
     "iopub.status.idle": "2024-01-27T09:59:12.009457Z",
     "shell.execute_reply": "2024-01-27T09:59:12.009457Z",
     "shell.execute_reply.started": "2024-01-27T09:59:11.518770Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "104"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h1 = image_hash(\"../new_data/similar_image_second/salt_pepper/kodim01.jpg\",64,32)\n",
    "h2 = image_hash(r\"C:\\Users\\10047\\Desktop\\temp\\salt_pepper\\kodim01\\kodim01_salt_pepper0.1.jpg\",64,32)\n",
    "dist_img(h1,h2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "id": "08293c14-4b28-405f-9900-da3150f0c233",
   "metadata": {
    "collapsed": true,
    "execution": {
     "iopub.execute_input": "2024-01-10T09:19:44.290946Z",
     "iopub.status.busy": "2024-01-10T09:19:44.290035Z",
     "iopub.status.idle": "2024-01-10T14:38:40.722636Z",
     "shell.execute_reply": "2024-01-10T14:38:40.721156Z",
     "shell.execute_reply.started": "2024-01-10T09:19:44.290880Z"
    },
    "jupyter": {
     "outputs_hidden": true
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "图像块为16大小的结果\n",
      "环数为图像块大小1倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：180平均值：18.68421052631579\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：138平均值：7.953333333333333\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：804平均值：353.7497487437186\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：804平均值：329.73007807807807\n",
      "旋转2°和set 200的auc值0.96744335713656\n",
      "旋转2°和set 1000的auc值0.9452372174806385\n",
      "旋转90°和set 200的auc值0.9799129815745393\n",
      "旋转90°和set 1000的auc值0.962120894227561\n",
      "环数为图像块大小2倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：148平均值：17.79824561403509\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：110平均值：8.473333333333333\n",
      "image_different_distance_200_标准化.xlsx的最小值：4最大值：754平均值：304.4510552763819\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：792平均值：286.4939219219219\n",
      "旋转2°和set 200的auc值0.995476670633871\n",
      "旋转2°和set 1000的auc值0.9926948834799711\n",
      "旋转90°和set 200的auc值0.9994272194304857\n",
      "旋转90°和set 1000的auc值0.9988449149149149\n",
      "环数为图像块大小3倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：78平均值：9.758771929824562\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：92平均值：8.753333333333334\n",
      "image_different_distance_200_标准化.xlsx的最小值：10最大值：740平均值：314.3321608040201\n",
      "image_different_distance_1000_标准化.xlsx的最小值：2最大值：764平均值：293.0905505505506\n",
      "旋转2°和set 200的auc值0.9998967975844132\n",
      "旋转2°和set 1000的auc值0.9998656507384579\n",
      "旋转90°和set 200的auc值0.9998833333333332\n",
      "旋转90°和set 1000的auc值0.9998361895228564\n",
      "环数为图像块大小4倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：74平均值：9.706140350877194\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：72平均值：9.186666666666667\n",
      "image_different_distance_200_标准化.xlsx的最小值：26最大值：636平均值：313.91668341708544\n",
      "image_different_distance_1000_标准化.xlsx的最小值：10最大值：712平均值：295.686994994995\n",
      "旋转2°和set 200的auc值0.9999419796350172\n",
      "旋转2°和set 1000的auc值0.999969328978101\n",
      "旋转90°和set 200的auc值0.9999428810720268\n",
      "旋转90°和set 1000的auc值0.9999765265265266\n",
      "环数为图像块大小5倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：98平均值：15.078947368421053\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：76平均值：9.593333333333334\n",
      "image_different_distance_200_标准化.xlsx的最小值：36最大值：602平均值：318.2661306532663\n",
      "image_different_distance_1000_标准化.xlsx的最小值：24最大值：704平均值：299.63804204204206\n",
      "旋转2°和set 200的auc值0.9999409327338447\n",
      "旋转2°和set 1000的auc值0.9999696033753052\n",
      "旋转90°和set 200的auc值0.9999479899497488\n",
      "旋转90°和set 1000的auc值0.9999937237237237\n",
      "环数为图像块大小6倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：96平均值：13.307017543859649\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：66平均值：9.486666666666666\n",
      "image_different_distance_200_标准化.xlsx的最小值：70最大值：622平均值：311.39316582914574\n",
      "image_different_distance_1000_标准化.xlsx的最小值：28最大值：708平均值：297.71751751751754\n",
      "旋转2°和set 200的auc值0.9999474345411266\n",
      "旋转2°和set 1000的auc值0.9999850815728009\n",
      "旋转90°和set 200的auc值0.9999497487437186\n",
      "旋转90°和set 1000的auc值0.9999961361361361\n",
      "\n",
      "图像块为32大小的结果\n",
      "环数为图像块大小1倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：44平均值：4.337719298245614\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：36平均值：1.9333333333333333\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：200平均值：87.73688442211055\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：200平均值：81.71471871871871\n",
      "旋转2°和set 200的auc值0.9502408974698052\n",
      "旋转2°和set 1000的auc值0.9252909137207382\n",
      "旋转90°和set 200的auc值0.9607575376884422\n",
      "旋转90°和set 1000的auc值0.9380102535869203\n",
      "环数为图像块大小2倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：38平均值：3.960526315789474\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：24平均值：1.88\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：190平均值：73.39909547738694\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：196平均值：68.87522722722723\n",
      "旋转2°和set 200的auc值0.9944177576478885\n",
      "旋转2°和set 1000的auc值0.9912376411499219\n",
      "旋转90°和set 200的auc值0.9991829983249582\n",
      "旋转90°和set 1000的auc值0.998434871538205\n",
      "环数为图像块大小3倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：22平均值：2.508771929824561\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：22平均值：2.12\n",
      "image_different_distance_200_标准化.xlsx的最小值：4最大值：172平均值：74.58854271356783\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：184平均值：69.34919319319319\n",
      "旋转2°和set 200的auc值0.9998215860001765\n",
      "旋转2°和set 1000的auc值0.9998067233900567\n",
      "旋转90°和set 200的auc值0.9997997487437187\n",
      "旋转90°和set 1000的auc值0.9997661127794462\n",
      "环数为图像块大小4倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：18平均值：2.3684210526315788\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：18平均值：2.1066666666666665\n",
      "image_different_distance_200_标准化.xlsx的最小值：8最大值：158平均值：75.43025125628141\n",
      "image_different_distance_1000_标准化.xlsx的最小值：2最大值：176平均值：71.02166966966966\n",
      "旋转2°和set 200的auc值0.999934926827118\n",
      "旋转2°和set 1000的auc值0.9999514316948527\n",
      "旋转90°和set 200的auc值0.9999419597989949\n",
      "旋转90°和set 1000的auc值0.9999714347681014\n",
      "环数为图像块大小5倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：26平均值：3.758771929824561\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：20平均值：2.7466666666666666\n",
      "image_different_distance_200_标准化.xlsx的最小值：16最大值：152平均值：76.85708542713567\n",
      "image_different_distance_1000_标准化.xlsx的最小值：6最大值：176平均值：72.2226986986987\n",
      "旋转2°和set 200的auc值0.9999408225337212\n",
      "旋转2°和set 1000的auc值0.9999457198426498\n",
      "旋转90°和set 200的auc值0.9999484924623115\n",
      "旋转90°和set 1000的auc值0.9999845779112446\n",
      "环数为图像块大小6倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：22平均值：3.9035087719298245\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：18平均值：2.8333333333333335\n",
      "image_different_distance_200_标准化.xlsx的最小值：8最大值：138平均值：74.39798994974875\n",
      "image_different_distance_1000_标准化.xlsx的最小值：8最大值：172平均值：70.99628828828828\n",
      "旋转2°和set 200的auc值0.9998895243762674\n",
      "旋转2°和set 1000的auc值0.9999694409321601\n",
      "旋转90°和set 200的auc值0.9998961474036852\n",
      "旋转90°和set 1000的auc值0.9999931097764431\n",
      "\n",
      "图像块为64大小的结果\n",
      "环数为图像块大小1倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：10平均值：0.9210526315789473\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：10平均值：0.36\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：50平均值：21.87939698492462\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：50平均值：20.432132132132132\n",
      "旋转2°和set 200的auc值0.9321057590584502\n",
      "旋转2°和set 1000的auc值0.9065434271991288\n",
      "旋转90°和set 200的auc值0.9409783082077052\n",
      "旋转90°和set 1000的auc值0.9169615382048715\n",
      "环数为图像块大小2倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：10平均值：1.0263157894736843\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：6平均值：0.42\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：46平均值：17.424723618090454\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：48平均值：16.298910910910912\n",
      "旋转2°和set 200的auc值0.989930133121749\n",
      "旋转2°和set 1000的auc值0.9851539939061869\n",
      "旋转90°和set 200的auc值0.9966652428810719\n",
      "旋转90°和set 1000的auc值0.9944007807807808\n",
      "环数为图像块大小3倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：6平均值：0.6842105263157895\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：6平均值：0.64\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：40平均值：17.448040201005025\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：44平均值：16.20057257257257\n",
      "旋转2°和set 200的auc值0.9994400731728821\n",
      "旋转2°和set 1000的auc值0.9991388757178231\n",
      "旋转90°和set 200的auc值0.9994527638190955\n",
      "旋转90°和set 1000的auc值0.9991707007007007\n",
      "环数为图像块大小4倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：8平均值：1.1140350877192982\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：4平均值：0.8266666666666667\n",
      "image_different_distance_200_标准化.xlsx的最小值：2最大值：38平均值：18.67738693467337\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：42平均值：17.523863863863863\n",
      "旋转2°和set 200的auc值0.9993379176584677\n",
      "旋转2°和set 1000的auc值0.9993503240082188\n",
      "旋转90°和set 200的auc值0.9995238693467337\n",
      "旋转90°和set 1000的auc值0.9996826793460126\n",
      "环数为图像块大小5倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：8平均值：1.206140350877193\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：8平均值：0.74\n",
      "image_different_distance_200_标准化.xlsx的最小值：4最大值：44平均值：20.644824120603015\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：46平均值：19.466234234234236\n",
      "旋转2°和set 200的auc值0.9998305122101736\n",
      "旋转2°和set 1000的auc值0.9996270129778903\n",
      "旋转90°和set 200的auc值0.9999178391959798\n",
      "旋转90°和set 1000的auc值0.999874044044044\n",
      "环数为图像块大小6倍的结果\n",
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：10平均值：1.236842105263158\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：6平均值：0.82\n",
      "image_different_distance_200_标准化.xlsx的最小值：4最大值：40平均值：21.049447236180903\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：46平均值：19.88247047047047\n",
      "旋转2°和set 200的auc值0.9992151547209732\n",
      "旋转2°和set 1000的auc值0.9994974140807474\n",
      "旋转90°和set 200的auc值0.9993924623115578\n",
      "旋转90°和set 1000的auc值0.999852042042042\n",
      "\n",
      "图像块为128大小的结果\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (13,) + inhomogeneous part.",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[132], line 5\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m j \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m7\u001b[39m):\n\u001b[1;32m      4\u001b[0m     n \u001b[38;5;241m=\u001b[39m j\u001b[38;5;241m*\u001b[39mi\n\u001b[0;32m----> 5\u001b[0m     data_similar_rotation_2 \u001b[38;5;241m=\u001b[39m \u001b[43mdis_similar_dir\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m../data/rotation_2/\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43mi\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m      6\u001b[0m     pd\u001b[38;5;241m.\u001b[39mDataFrame(data_similar_rotation_2)\u001b[38;5;241m.\u001b[39mto_excel(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m./结果/纯四元数_环形分区_RGB空间结果/image_similar_distance_2_标准化.xlsx\u001b[39m\u001b[38;5;124m\"\u001b[39m,index \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[1;32m      8\u001b[0m     data_similar_rotation_90 \u001b[38;5;241m=\u001b[39m dis_similar_dir(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m../data/rotation_90/\u001b[39m\u001b[38;5;124m\"\u001b[39m,n,i)\n",
      "Cell \u001b[0;32mIn[131], line 180\u001b[0m, in \u001b[0;36mdis_similar_dir\u001b[0;34m(path, n, image_block_size)\u001b[0m\n\u001b[1;32m    177\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m dir_rotation:\n\u001b[1;32m    178\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39msplitext(i)[\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m.bmp\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m    179\u001b[0m \u001b[38;5;66;03m#             print(os.path.join(path, i)) # 用于查看路径是否有中文\u001b[39;00m\n\u001b[0;32m--> 180\u001b[0m             h1 \u001b[38;5;241m=\u001b[39m \u001b[43mimage_hash\u001b[49m\u001b[43m(\u001b[49m\u001b[43mos\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpath\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mi\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43mimage_block_size\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    181\u001b[0m             dir_temp \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(path,os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39msplitext(i)[\u001b[38;5;241m0\u001b[39m])\n\u001b[1;32m    182\u001b[0m             \u001b[38;5;28;01mfor\u001b[39;00m j \u001b[38;5;129;01min\u001b[39;00m os\u001b[38;5;241m.\u001b[39mlistdir(dir_temp):\n",
      "Cell \u001b[0;32mIn[131], line 3\u001b[0m, in \u001b[0;36mimage_hash\u001b[0;34m(img_path, n, image_block_size)\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mimage_hash\u001b[39m(img_path,n,image_block_size):\n\u001b[1;32m      2\u001b[0m     img \u001b[38;5;241m=\u001b[39m processing(img_path,n)\n\u001b[0;32m----> 3\u001b[0m     C_r_list \u001b[38;5;241m=\u001b[39m \u001b[43mimage_feature\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m,\u001b[49m\u001b[43mimage_block_size\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m      4\u001b[0m     h_i \u001b[38;5;241m=\u001b[39m gen_hashing(C_r_list)\n\u001b[1;32m      5\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m h_i\n",
      "Cell \u001b[0;32mIn[131], line 91\u001b[0m, in \u001b[0;36mimage_feature\u001b[0;34m(img, image_block_size)\u001b[0m\n\u001b[1;32m     89\u001b[0m         C_r_list\u001b[38;5;241m.\u001b[39mappend(np\u001b[38;5;241m.\u001b[39msqrt(C_r\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m\u001b[38;5;241m+\u001b[39mC_i\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m\u001b[38;5;241m+\u001b[39mC_j\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m\u001b[38;5;241m+\u001b[39mC_k\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m)\u001b[38;5;241m.\u001b[39mtolist())\n\u001b[1;32m     90\u001b[0m         \u001b[38;5;66;03m# C_r_list.append(C_r.tolist())\u001b[39;00m\n\u001b[0;32m---> 91\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mC_r_list\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[0;31mValueError\u001b[0m: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (13,) + inhomogeneous part."
     ]
    }
   ],
   "source": [
    "for i in (16,32,64,128):\n",
    "    print(f\"图像块为{i}大小的结果\")\n",
    "    for j in range(1,7):\n",
    "        n = j*i\n",
    "        data_similar_rotation_2 = dis_similar_dir(\"../data/rotation_2/\",n,i)\n",
    "        pd.DataFrame(data_similar_rotation_2).to_excel(\"./结果/纯四元数_环形分区_RGB空间结果/image_similar_distance_2_标准化.xlsx\",index = False)\n",
    "        \n",
    "        data_similar_rotation_90 = dis_similar_dir(\"../data/rotation_90/\",n,i)\n",
    "        pd.DataFrame(data_similar_rotation_90).to_excel(\"./结果/纯四元数_环形分区_RGB空间结果/image_similar_distance_90_标准化.xlsx\",index = False)\n",
    "        \n",
    "        data_different_set_200,_ = dis_different_dir(\"../data/Image Set 200/\",n,i)\n",
    "        pd.DataFrame(data_different_set_200).to_excel(\"./结果/纯四元数_环形分区_RGB空间结果/image_different_distance_200_标准化.xlsx\",index = False)\n",
    "        \n",
    "        data_different_set_1000,_ = dis_different_dir(\"../data/Image Set 1000/\",n,i)\n",
    "        pd.DataFrame(data_different_set_1000).to_excel(\"./结果/纯四元数_环形分区_RGB空间结果/image_different_distance_1000_标准化.xlsx\",index = False)\n",
    "        print(f\"环数为图像块大小{j}倍的结果\")\n",
    "        stat_analysis(\"./结果/纯四元数_环形分区_RGB空间结果/\")\n",
    "        auc_analysis(\"./结果/纯四元数_环形分区_RGB空间结果/\")\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "id": "d7d74845-b306-42a7-ba06-40687ba465e1",
   "metadata": {
    "collapsed": true,
    "execution": {
     "iopub.execute_input": "2024-01-09T03:01:55.233711Z",
     "iopub.status.busy": "2024-01-09T03:01:55.232104Z",
     "iopub.status.idle": "2024-01-09T03:01:55.593010Z",
     "shell.execute_reply": "2024-01-09T03:01:55.592082Z",
     "shell.execute_reply.started": "2024-01-09T03:01:55.233589Z"
    },
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3200\n",
      "3197 3197 3197\n",
      "3196 3196 3196\n",
      "3216 3216 3216\n",
      "3192 3192 3192\n",
      "3204 3204 3204\n",
      "3200 3200 3200\n",
      "3208 3208 3208\n",
      "3200 3200 3200\n",
      "3180 3180 3180\n",
      "3188 3188 3188\n",
      "3208 3208 3208\n",
      "3228 3228 3228\n",
      "3176 3176 3176\n",
      "3204 3204 3204\n",
      "3204 3204 3204\n",
      "3212 3212 3212\n",
      "3204 3204 3204\n",
      "3200 3200 3200\n",
      "3180 3180 3180\n",
      "3204 3204 3204\n",
      "3212 3212 3212\n",
      "3196 3196 3196\n",
      "3212 3212 3212\n",
      "3204 3204 3204\n",
      "3172 3172 3172\n",
      "3176 3176 3176\n",
      "3188 3188 3188\n",
      "3212 3212 3212\n",
      "3236 3236 3236\n",
      "3188 3188 3188\n",
      "3204 3204 3204\n",
      "3188 3188 3188\n",
      "3212 3212 3212\n",
      "3220 3220 3220\n",
      "3160 3160 3160\n",
      "3244 3244 3244\n",
      "3172 3172 3172\n",
      "3208 3208 3208\n",
      "3200 3200 3200\n",
      "3192 3192 3192\n",
      "3180 3180 3180\n",
      "3224 3224 3224\n",
      "3168 3168 3168\n",
      "3264 3264 3264\n",
      "3140 3140 3140\n",
      "3256 3256 3256\n",
      "3148 3148 3148\n",
      "3244 3244 3244\n",
      "3196 3196 3196\n",
      "3192 3192 3192\n",
      "3176 3176 3176\n",
      "3216 3216 3216\n",
      "3200 3200 3200\n",
      "3196 3196 3196\n",
      "3216 3216 3216\n",
      "3164 3164 3164\n",
      "3160 3160 3160\n",
      "3272 3272 3272\n",
      "3192 3192 3192\n",
      "3220 3220 3220\n",
      "3216 3216 3216\n",
      "3180 3180 3180\n",
      "3232 3232 3232\n",
      "3140 3140 3140\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 0, 0])"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_hash(\"../data/Lenna_(test_image).png\",64)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "280d08c5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-12-06T03:06:29.525926Z",
     "start_time": "2023-12-06T03:06:29.514955Z"
    },
    "collapsed": true,
    "execution": {
     "iopub.execute_input": "2024-01-07T08:39:28.091802Z",
     "iopub.status.busy": "2024-01-07T08:39:28.090169Z",
     "iopub.status.idle": "2024-01-07T09:55:37.646622Z",
     "shell.execute_reply": "2024-01-07T09:55:37.645606Z",
     "shell.execute_reply.started": "2024-01-07T08:39:28.091702Z"
    },
    "jupyter": {
     "outputs_hidden": true
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:06<00:00,  8.92it/s]\n",
      "100%|█████████████| 57/57 [00:06<00:00,  9.15it/s]\n",
      "100%|█████████████| 57/57 [00:06<00:00,  9.16it/s]\n",
      "100%|█████████████| 57/57 [00:05<00:00,  9.56it/s]\n",
      "100%|█████████████| 57/57 [00:05<00:00,  9.60it/s]\n",
      "100%|█████████████| 57/57 [00:05<00:00,  9.53it/s]\n",
      "100%|█████████████| 57/57 [00:05<00:00,  9.53it/s]\n",
      "100%|█████████████| 57/57 [00:06<00:00,  9.27it/s]\n",
      "100%|█████████████| 44/44 [00:04<00:00,  9.76it/s]\n",
      "100%|█████████████| 16/16 [00:01<00:00,  8.72it/s]\n",
      "100%|█████████████| 44/44 [00:04<00:00,  9.33it/s]\n",
      "100%|█████████████| 16/16 [00:01<00:00,  9.82it/s]\n",
      "100%|█████████████| 44/44 [00:04<00:00,  9.22it/s]\n",
      "100%|█████████████| 16/16 [00:01<00:00,  8.91it/s]\n",
      "100%|█████████████| 44/44 [00:04<00:00,  9.78it/s]\n",
      "100%|█████████████| 16/16 [00:01<00:00,  9.25it/s]\n",
      "100%|█████████████| 44/44 [00:04<00:00,  9.31it/s]\n",
      "100%|█████████████| 16/16 [00:01<00:00,  9.16it/s]\n",
      "100%|███████████| 200/200 [00:22<00:00,  8.85it/s]\n",
      "100%|█████████| 1000/1000 [01:53<00:00,  8.83it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当环数为64时：\n",
      "旋转2°和set 200的auc值0.8611801882218109\n",
      "旋转2°和set 1000的auc值0.813113029696363\n",
      "旋转90°和set 200的auc值0.797321608040201\n",
      "旋转90°和set 1000的auc值0.7527184084084084\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:09<00:00,  5.73it/s]\n",
      "100%|█████████████| 57/57 [00:10<00:00,  5.51it/s]\n",
      "100%|█████████████| 57/57 [00:09<00:00,  5.72it/s]\n",
      "100%|█████████████| 57/57 [00:10<00:00,  5.68it/s]\n",
      "100%|█████████████| 57/57 [00:10<00:00,  5.45it/s]\n",
      "100%|█████████████| 57/57 [00:09<00:00,  5.78it/s]\n",
      "100%|█████████████| 57/57 [00:09<00:00,  5.79it/s]\n",
      "100%|█████████████| 57/57 [00:09<00:00,  5.71it/s]\n",
      "100%|█████████████| 44/44 [00:07<00:00,  5.63it/s]\n",
      "100%|█████████████| 16/16 [00:02<00:00,  5.86it/s]\n",
      "100%|█████████████| 44/44 [00:07<00:00,  5.60it/s]\n",
      "100%|█████████████| 16/16 [00:02<00:00,  5.67it/s]\n",
      "100%|█████████████| 44/44 [00:07<00:00,  5.66it/s]\n",
      "100%|█████████████| 16/16 [00:02<00:00,  5.82it/s]\n",
      "100%|█████████████| 44/44 [00:07<00:00,  5.73it/s]\n",
      "100%|█████████████| 16/16 [00:03<00:00,  5.31it/s]\n",
      "100%|█████████████| 44/44 [00:07<00:00,  5.50it/s]\n",
      "100%|█████████████| 16/16 [00:02<00:00,  5.58it/s]\n",
      "100%|███████████| 200/200 [00:37<00:00,  5.33it/s]\n",
      "100%|█████████| 1000/1000 [03:00<00:00,  5.52it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当环数为128时：\n",
      "旋转2°和set 200的auc值0.9692299215375121\n",
      "旋转2°和set 1000的auc值0.9673081963542489\n",
      "旋转90°和set 200的auc值0.9262006700167504\n",
      "旋转90°和set 1000的auc值0.9242389856523189\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:13<00:00,  4.17it/s]\n",
      "100%|█████████████| 57/57 [00:13<00:00,  4.22it/s]\n",
      "100%|█████████████| 57/57 [00:14<00:00,  3.97it/s]\n",
      "100%|█████████████| 57/57 [00:13<00:00,  4.13it/s]\n",
      "100%|█████████████| 57/57 [00:13<00:00,  4.20it/s]\n",
      "100%|█████████████| 57/57 [00:13<00:00,  4.16it/s]\n",
      "100%|█████████████| 57/57 [00:13<00:00,  4.21it/s]\n",
      "100%|█████████████| 57/57 [00:13<00:00,  4.14it/s]\n",
      "100%|█████████████| 44/44 [00:11<00:00,  3.85it/s]\n",
      "100%|█████████████| 16/16 [00:03<00:00,  4.26it/s]\n",
      "100%|█████████████| 44/44 [00:11<00:00,  3.97it/s]\n",
      "100%|█████████████| 16/16 [00:03<00:00,  4.02it/s]\n",
      "100%|█████████████| 44/44 [00:10<00:00,  4.14it/s]\n",
      "100%|█████████████| 16/16 [00:03<00:00,  4.25it/s]\n",
      "100%|█████████████| 44/44 [00:10<00:00,  4.09it/s]\n",
      "100%|█████████████| 16/16 [00:03<00:00,  4.16it/s]\n",
      "100%|█████████████| 44/44 [00:10<00:00,  4.22it/s]\n",
      "100%|█████████████| 16/16 [00:03<00:00,  4.11it/s]\n",
      "100%|███████████| 200/200 [00:50<00:00,  3.98it/s]\n",
      "100%|█████████| 1000/1000 [04:07<00:00,  4.04it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当环数为192时：\n",
      "旋转2°和set 200的auc值0.9747090165740986\n",
      "旋转2°和set 1000的auc值0.9697872741162216\n",
      "旋转90°和set 200的auc值0.9311483249581239\n",
      "旋转90°和set 1000的auc值0.9226923790457124\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:17<00:00,  3.20it/s]\n",
      "100%|█████████████| 57/57 [00:18<00:00,  3.13it/s]\n",
      "100%|█████████████| 57/57 [00:17<00:00,  3.20it/s]\n",
      "100%|█████████████| 44/44 [00:14<00:00,  2.99it/s]\n",
      "100%|█████████████| 16/16 [00:05<00:00,  3.18it/s]\n",
      "100%|█████████████| 44/44 [00:14<00:00,  3.14it/s]\n",
      "100%|█████████████| 16/16 [00:05<00:00,  3.08it/s]\n",
      "100%|█████████████| 44/44 [00:13<00:00,  3.21it/s]\n",
      "100%|█████████████| 16/16 [00:04<00:00,  3.30it/s]\n",
      "100%|█████████████| 44/44 [00:13<00:00,  3.26it/s]\n",
      "100%|█████████████| 16/16 [00:04<00:00,  3.27it/s]\n",
      "100%|███████████| 200/200 [01:03<00:00,  3.15it/s]\n",
      "100%|█████████| 1000/1000 [05:19<00:00,  3.13it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当环数为256时：\n",
      "旋转2°和set 200的auc值0.970141056157983\n",
      "旋转2°和set 1000的auc值0.9722797534376482\n",
      "旋转90°和set 200的auc值0.9365400335008376\n",
      "旋转90°和set 1000的auc值0.9403630530530531\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:22<00:00,  2.56it/s]\n",
      "100%|█████████████| 57/57 [00:21<00:00,  2.59it/s]\n",
      "100%|█████████████| 57/57 [00:21<00:00,  2.66it/s]\n",
      "100%|█████████████| 57/57 [00:22<00:00,  2.51it/s]\n",
      "100%|█████████████| 57/57 [00:22<00:00,  2.57it/s]\n",
      "100%|█████████████| 57/57 [00:22<00:00,  2.51it/s]\n",
      "100%|█████████████| 57/57 [00:22<00:00,  2.55it/s]\n",
      "100%|█████████████| 57/57 [00:21<00:00,  2.60it/s]\n",
      "100%|█████████████| 44/44 [00:16<00:00,  2.62it/s]\n",
      "100%|█████████████| 16/16 [00:06<00:00,  2.60it/s]\n",
      "100%|█████████████| 44/44 [00:17<00:00,  2.58it/s]\n",
      "100%|█████████████| 16/16 [00:06<00:00,  2.46it/s]\n",
      "100%|█████████████| 44/44 [00:16<00:00,  2.60it/s]\n",
      "100%|█████████████| 16/16 [00:06<00:00,  2.57it/s]\n",
      "100%|█████████████| 44/44 [00:17<00:00,  2.52it/s]\n",
      "100%|█████████████| 16/16 [00:06<00:00,  2.59it/s]\n",
      "100%|█████████████| 44/44 [00:17<00:00,  2.55it/s]\n",
      "100%|█████████████| 16/16 [00:06<00:00,  2.57it/s]\n",
      "100%|███████████| 200/200 [01:17<00:00,  2.57it/s]\n",
      " 80%|████████  | 804/1000 [05:10<01:17,  2.52it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "旋转2°和set 200的auc值0.9680450498104558\n",
      "旋转2°和set 1000的auc值0.9702504236692833\n",
      "旋转90°和set 200的auc值0.9347285594639867\n",
      "旋转90°和set 1000的auc值0.9385615015015015\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:25<00:00,  2.24it/s]\n",
      "100%|█████████████| 57/57 [00:25<00:00,  2.24it/s]\n",
      "100%|█████████████| 57/57 [00:25<00:00,  2.21it/s]\n",
      "100%|█████████████| 57/57 [00:26<00:00,  2.19it/s]\n",
      "100%|█████████████| 57/57 [00:25<00:00,  2.26it/s]\n",
      "100%|█████████████| 57/57 [00:25<00:00,  2.27it/s]\n",
      "100%|█████████████| 57/57 [00:25<00:00,  2.23it/s]\n",
      "100%|█████████████| 57/57 [00:25<00:00,  2.22it/s]\n",
      "100%|█████████████| 44/44 [00:20<00:00,  2.19it/s]\n",
      "100%|█████████████| 16/16 [00:07<00:00,  2.09it/s]\n",
      "100%|█████████████| 44/44 [00:19<00:00,  2.20it/s]\n",
      "100%|█████████████| 16/16 [00:07<00:00,  2.22it/s]\n",
      "100%|█████████████| 44/44 [00:19<00:00,  2.23it/s]\n",
      "100%|█████████████| 16/16 [00:07<00:00,  2.25it/s]\n",
      "100%|█████████████| 44/44 [00:19<00:00,  2.22it/s]\n",
      "100%|█████████████| 16/16 [00:07<00:00,  2.08it/s]\n",
      "100%|█████████████| 44/44 [00:19<00:00,  2.27it/s]\n",
      "100%|█████████████| 16/16 [00:07<00:00,  2.26it/s]\n",
      "100%|███████████| 200/200 [01:31<00:00,  2.19it/s]\n",
      "100%|█████████| 1000/1000 [07:29<00:00,  2.23it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当环数为384时：\n",
      "旋转2°和set 200的auc值0.9770526425989599\n",
      "旋转2°和set 1000的auc值0.985989570711062\n",
      "旋转90°和set 200的auc值0.946080569514238\n",
      "旋转90°和set 1000的auc值0.9626324524524524\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 57/57 [00:29<00:00,  1.94it/s]\n",
      "100%|█████████████| 57/57 [00:29<00:00,  1.92it/s]\n",
      "100%|█████████████| 57/57 [00:29<00:00,  1.91it/s]\n",
      "100%|█████████████| 57/57 [00:29<00:00,  1.94it/s]\n",
      "100%|█████████████| 57/57 [00:29<00:00,  1.94it/s]\n",
      "100%|█████████████| 57/57 [00:29<00:00,  1.96it/s]\n",
      "100%|█████████████| 57/57 [00:28<00:00,  2.00it/s]\n",
      "100%|█████████████| 57/57 [00:29<00:00,  1.92it/s]\n",
      "100%|█████████████| 44/44 [00:22<00:00,  1.98it/s]\n",
      "100%|█████████████| 16/16 [00:07<00:00,  2.02it/s]\n",
      "100%|█████████████| 44/44 [00:22<00:00,  1.97it/s]\n",
      "100%|█████████████| 16/16 [00:08<00:00,  1.99it/s]\n",
      "100%|█████████████| 44/44 [00:22<00:00,  1.99it/s]\n",
      "100%|█████████████| 16/16 [00:08<00:00,  1.98it/s]\n",
      "100%|█████████████| 44/44 [00:22<00:00,  1.95it/s]\n",
      "100%|█████████████| 16/16 [00:08<00:00,  1.99it/s]\n",
      "100%|█████████████| 44/44 [00:22<00:00,  1.93it/s]\n",
      "100%|█████████████| 16/16 [00:08<00:00,  1.93it/s]\n",
      "100%|███████████| 200/200 [01:43<00:00,  1.94it/s]\n",
      "100%|█████████| 1000/1000 [08:44<00:00,  1.91it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当环数为448时：\n",
      "旋转2°和set 200的auc值0.9408786806841224\n",
      "旋转2°和set 1000的auc值0.9598257621656744\n",
      "旋转90°和set 200的auc值0.9268917922948073\n",
      "旋转90°和set 1000的auc值0.9490557891224557\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# for i in range(1,8):\n",
    "#     n = i*64\n",
    "#     data_similar_rotation_2 = dis_similar_dir(\"../data/rotation_2/\",n)\n",
    "#     pd.DataFrame(data_similar_rotation_2).to_excel(\"./结果/纯四元数_环形分区结果/image_similar_distance_2_标准化.xlsx\",index = False)\n",
    "    \n",
    "#     data_similar_rotation_90 = dis_similar_dir(\"../data/rotation_90/\",n)\n",
    "#     pd.DataFrame(data_similar_rotation_90).to_excel(\"./结果/纯四元数_环形分区结果/image_similar_distance_90_标准化.xlsx\",index = False)\n",
    "    \n",
    "#     data_different_set_200,_ = dis_different_dir(\"../data/Image Set 200/\",n)\n",
    "#     pd.DataFrame(data_different_set_200).to_excel(\"./结果/纯四元数_环形分区结果/image_different_distance_200_标准化.xlsx\",index = False)\n",
    "    \n",
    "#     data_different_set_1000,_ = dis_different_dir(\"../data/Image Set 1000/\",n)\n",
    "#     pd.DataFrame(data_different_set_1000).to_excel(\"./结果/纯四元数_环形分区结果/image_different_distance_1000_标准化.xlsx\",index = False)\n",
    "#     print(f\"当环数为{n}时：\")\n",
    "#     auc_analysis(\"./结果/纯四元数_环形分区结果/\")\n",
    "#     print()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "9479c27b-41e7-4f1a-82b8-6277938ce1ea",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-01-07T08:32:33.305216Z",
     "iopub.status.busy": "2024-01-07T08:32:33.302933Z",
     "iopub.status.idle": "2024-01-07T08:32:54.721336Z",
     "shell.execute_reply": "2024-01-07T08:32:54.720226Z",
     "shell.execute_reply.started": "2024-01-07T08:32:33.305132Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "image_similar_distance_2_标准化.xlsx的最小值：0最大值：22平均值：3.662280701754386\n",
      "image_similar_distance_90_标准化.xlsx的最小值：0最大值：46平均值：7.226666666666667\n",
      "image_different_distance_200_标准化.xlsx的最小值：0最大值：50平均值：23.45527638190955\n",
      "image_different_distance_1000_标准化.xlsx的最小值：0最大值：50平均值：21.99212012012012\n",
      "旋转2°和set 200的auc值0.8611801882218109\n",
      "旋转2°和set 1000的auc值0.813113029696363\n",
      "旋转90°和set 200的auc值0.797321608040201\n",
      "旋转90°和set 1000的auc值0.7527184084084084\n"
     ]
    }
   ],
   "source": [
    "stat_analysis(\"./结果/纯四元数_环形分区结果/\")\n",
    "auc_analysis(\"./结果/纯四元数_环形分区结果/\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "5ed33d2b-7fd9-4a66-aa4a-dab1b5da2ecf",
   "metadata": {
    "collapsed": true,
    "execution": {
     "iopub.execute_input": "2024-01-04T13:45:51.825952Z",
     "iopub.status.busy": "2024-01-04T13:45:51.824408Z",
     "iopub.status.idle": "2024-01-04T13:45:52.722733Z",
     "shell.execute_reply": "2024-01-04T13:45:52.721782Z",
     "shell.execute_reply.started": "2024-01-04T13:45:51.825859Z"
    },
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAyXElEQVR4nO3de1xU5b7H8e9wGzG5GYI30tKtaN7KisikbJN2ozr7tLP0eKu8lF2UbrqtzC5a7Y7ZSdM0K3fb0u67s/VYhpmalIVyjrtQMyzNAtSUIVAGmHX+KCZHUBhk5mGYz/v1mhczi/XM/GbFq/X1eZ71LJtlWZYAAAAMCTFdAAAACG6EEQAAYBRhBAAAGEUYAQAARhFGAACAUYQRAABgFGEEAAAYRRgBAABGhZkuoD5cLpd+/PFHRUVFyWazmS4HAADUg2VZKikpUfv27RUScvz+j4AIIz/++KOSkpJMlwEAABpgz5496tix43F/HxBhJCoqStKvXyY6OtpwNQAAoD4cDoeSkpLc5/HjCYgwUj00Ex0dTRgBACDA1DXFggmsAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwCivw8i6deuUkZGh9u3by2az6b333quzzdq1a3X22WfLbrera9eueuWVVxpQKgAAaI68DiOlpaXq27ev5s2bV6/9d+3apSuvvFKDBg1Sbm6uJk2apFtuuUUffPCB18UCAIDmx+t701x++eW6/PLL673/ggULdPrpp+s///M/JUk9evTQhg0b9Mwzz2jIkCHefjwAAGhmfH6jvOzsbKWnp3tsGzJkiCZNmnTcNuXl5SovL3e/djgcvioPABCEduzYoe+//16HDh3SoUOHVFxcXOvzwYMH68EHH/Ro27dvXxUUFNT5Gc8884yGDRvmfp2Xl6eLL764XvXl5uaqXbt27tfPP/+8ZsyYUWe75ORkffLJJx7b/vznP2vdunUnbLd27Vr16NGjXrX5gs/DSEFBgRITEz22JSYmyuFw6PDhw4qMjKzRZtasWfU66ACA4GBZlizLUkjI77MLdu/erfXr19cIEccGi4iICP3f//2fx/s98sgjWrp0aZ2f26FDhxrb9u/fr6KiojrbHjlyxON1VVVVvdpJksvl8nhdVlZWr7Zt2rSpse3QoUN1tq2srKxXXb7i8zDSEFOnTlVmZqb7tcPhUFJSksGKAADVLMuqcUv4wsJClZSUyOl0nvDRtWtX9evXz93O5XLpqaee0uHDh4/bO1FcXKzi4mJ9+umnOv/8891tN23apP/4j/+os1673V5jW2xsbL2+a2lpaY1tp512Wq3veayoqCiP1+Hh4Tr99NPr9bmhoaEer2NiYurVtmPHjjW2tW3bts624eHh9arLV3weRtq2bavCwkKPbYWFhYqOjq61V0T69Q+nPv+hAaC5Kioq0pEjR1RRUeE+kR/9vPp1r1691KlTJ3e7AwcO6NVXX62xb22P5557Tq1bt3a3ff311zVnzpxa9y0vL3c/79atm/71r3951DtixAitXr26zu81efJkjzBis9k0derUeh2T4uJij9cxMTF1tomOjlZsbKycTqciIiLc2y+77DLFxcUpNjZWMTExHj+rn8fExNR6LsrOzq5Xvcfq3r278vPzG9R27NixGjt2bIPavvrqqw1q508+DyOpqalauXKlx7bVq1crNTXV1x8NAJJ+/df3d9995z5B13aCr/558cUXKz4+3t32m2++0XvvvVdrIDj6eWhoaI1lC5588km9/fbbJ/y8iooKZWRkaPny5R5tzznnHO3Zs6fO7/bCCy9o3Lhx7tf79u3T5MmT63VcHn/8cY8wsm/fPm3atKnOdk6ns8a2o0/03rS12WwKDw9XRUVFjX3DwsIUFxfnDgnHBoOePXvq2Wef9QgQR/+Mioqq0cNQ7aqrrtJVV11Vr5rhe16HkV9++UU7d+50v961a5dyc3PVunVrnXbaaZo6dar27t2rv/3tb5KkCRMmaO7cubrvvvt00003ac2aNXrjjTe0YsWKxvsWAILCL7/8oqKiouM+9u3bp6KiIk2YMEG33nqru115ebm6dOlSr8/45JNPlJaW5n791Vdf6b777quznd1urxFGvv/+e33xxRd1tj18+HCNbQ09ude33Yna2u12RUREHPdx2mmn1Xiviy++WHFxcSdsFxERobPOOqtG27ffflthYWHuUFEdKCIjI2sMBx2tQ4cOuvPOO+v9fdF0eR1GvvzySw0aNMj9unpux6hRo/TKK6/op59+0u7du92/P/3007VixQpNnjxZzz77rDp27KgXX3yRy3oBqLy83B0gqn9WP6KjozVt2jSP/YcMGaKNGzfW+b7HdoV7Mx7e0JO70+msMZciPDxcNpvNfSIODw/3+Fn9/OhhlmqXXXaZioqKauxf/To8PFx2u10pKSke7RITE/X666/XGQoiIiJqzC8YP368xo8ff8IAcDz33HOP122qZWRkNLgtmgebZVmW6SLq4nA4FBMTo+LiYkVHR5suB8BxVFVV6cCBAx6hIiMjQ6eccop7n6VLl2rGjBkqKiqqMQfgaF27dtU333zjse3aa6/VP/7xjxPWYLfbNX78eD377LPubZZlafjw4bUGgmN/XnfddercubO7bUFBgTZu3FgjQNQWMDp16uRxIne5XB5XfwDBpr7n7yZ5NQ2ApsGyLDkcDtlsNo//kfz888+aPn16jeGR/fv369h/33z11Vfq2bOn+3VFRUWNkFGb2i5FTEtLU2RkpBISEjwebdq0cT+Pioqq8S97m82m1157zduvL+nXSfh/+tOfGtSWIALUD2EECGLr1q1Tfn7+CedhVFRUaObMmR5XPNhsNs2dO7den1FUVOQRRhISEhQbG1sjRNQWMI519CX/AJoPwggQBMrKyvTDDz+oW7duHtsfeOABrV+/vs72x/ZSxMbGKiwszL1QUosWLZSYmFhrb8XRQx6SdMUVV+jgwYMn94UANCuEEaAZOnjwoD799FOtX79e69at05dffqnk5GRt3brVY7+EhIRa24eGhnr0WnTt2tXj9zabTZ999pni4uKUkJCgU045pUGTHgFAYgIr0CwUFBS4g8e6deu0devWGnM3pF+XsT711FPdr1esWKHvv/++xhBJbGws8x0AnDQmsAJBYv369R7rYtQmOTlZaWlpNdazuPLKK31ZGgDUC2EEaOJcLpfy8vLcPR8ZGRm68cYb3b8/66yzFBoaqqqqKkm/XsHRr18/paWlaeDAgbrwwguPOxwDAE0BYQRoYiorK5Wbm6t169Zp/fr1Wr9+vQ4cOOD+vc1m8wgjrVq10k033aT4+HilpaXpggsuYDgTQEAhjABNxFtvvaVFixZp48aN+uWXX467X05OTo1tCxcu9GVpAOBThBHAzxwOhzZu3KhLLrnEY6nx3bt368MPP6yxf+vWrXXhhRcqLS1NaWlpHnc8BYDmgDAC+Ni+ffu0YcMG95Uuubm5crlc2rhxo8fdqwcOHChJat++vXu+R1pamnr27MmVLQCaNcII0Mh2797tnmy6fv165eXl1brfunXrPMLIWWedpZ07d+qMM85gzQ4AQYUwApyEioqKGneEvfjii7Vr167jtundu7fS0tI8gogkhYWF1fs29wDQnBBGgDpYlqWioiJt27ZN27ZtU15envt5SEhIjdvVp6WlucNIaGiozjnnHPeQy4ABA9S6dWsTXwMAmizCCFCLf/3rX5o9e7Y7eBw6dOi4+5aVlally5bu10OHDlWnTp00cOBAnX/++WrVqpUfKgaAwEUYQdApKSnR9u3bPXo5Jk2a5J5AKkmlpaV6+eWXT/g+MTEx6tGjhw4cOOARRi6//HJdfvnlPqsfAJobwgiater7tBwdPPbu3VtjvwsvvNAjjHTv3t39/LTTTlNycrL70aNHDyUnJysxMZGJpgDQCAgjCGhOp1Pffvuttm3bpoqKCl1//fUev580aZK2bNlS5/ts377d43VsbKy2bNmirl27MswCAD5GGEFAsCxLmzdvdvdyVPd0fPvtt+57snTt2rVGGElOTvYII61bt3b3bFT/TE5OVufOnWt8JouLAYB/EEbQ5P3P//yP7rnnHn399dcn3C8/P1/l5eWy2+3ubaNHj9agQYPc4SM+Pt7X5QIAvEQYQZNXWVlZaxCJjIxU9+7dPeZzWJblsc/gwYP9VSYAoIEII2hSvvrqK1VWVqpv377ubVdeeaW6deumhIQE/elPf3IPr5x22mkskw4AzQBhBMZZlqWPPvpIs2fP1qpVq3TppZd63DAuJCRE2dnZLBYGAM0U/6yEMeXl5Xr55ZfVp08fDR48WKtWrZIkrV69Wlu3bvXYlyACAM0XPSPwu/3792vBggWaO3euCgsLPX7XuXNnTZo0qdarWwAAzRNhBH5TWVmp22+/XUuWLNGRI0c8fpeamqq7775b11xzjcLC+LMEgGDC//XhN2FhYdqxY4c7iISEhOjf//3fNXny5Bp3sAUABA/mjMAnnE6n3nrrLblcLo/tmZmZioqK0uTJk/Xtt9/qjTfeIIgAQJCjZwSN6ueff9YLL7yg5557Tj/99JNWrlzpcdO4K664Qnv27FFMTIzBKgEATQk9I2gU33zzjSZOnKikpCT95S9/0U8//SRJmj17tsd+ISEhBBEAgAd6RtBglmVp/fr1mj17tt5//32P1U9tNpuuvfZaZWZmGqwQABAICCNokI0bN+rOO+9UTk6Ox/ZTTjlFN910k+666y516dLFUHUAgEBCGEGDREZGegSRDh066M4779TYsWMVFxdnsDIAQKAhjKBeXC6Xx31gzjrrLA0aNEjFxcW6++679ec//1nh4eEGKwQABCrCCE7o8OHDmjlzprKzs/Xhhx96BJJ33nlHMTExstlsBisEAAQ6rqbBca1atUq9evXSY489pqysLC1ZssTj97GxsQQRAMBJI4yghh9//FHXX3+9Lr/8cuXn50uSwsPDVVRUZLgyAEBzxDAN3CorK/X888/rgQceUElJiXt7Wlqa5s+fr549exqsDgDQXBFGIEn64osvNGHCBG3evNm9LT4+Xk8//bRGjhzJcAwAwGcII9CuXbuUmpqqqqoq97axY8dq1qxZOvXUUw1WBgAIBswZgU4//XSNGjVKktS7d29t2LBBCxcuJIgAAPyCnpEgtGvXLnXq1MnjMt0nn3xSvXv31sSJE1kvBADgV/SMBJEjR47o4YcfVnJysl588UWP38XHx2vSpEkEEQCA3xFGgsSHH36o3r17a8aMGXI6nbr//vu5VBcA0CQQRpq5n376STfeeKOGDBminTt3SpLCwsI0YcIEnXLKKYarAwCAOSPNVlVVlebPn69p06bJ4XC4tw8cOFDz58/XmWeeabA6AAB+Rxhphr788ktNmDDB4666p556qp5++mmNGjWKNUMAAE0KwzTN0OLFiz2CyM0336zt27dr9OjRBBEAQJNjsyzLMl1EXRwOh2JiYlRcXKzo6GjT5TR5Bw8eVHJyshISErRgwQINGDDAdEkAgCBU3/M3wzQBzul0qqqqSpGRke5tcXFxWrNmjbp168alugCAJo9hmgA3ZcoUpaSkKC8vz2P7mWeeSRABAAQEekYC2D//+U8988wzkqQBAwbou+++YxgLABBw6BkJUD/88INGjx7tfv3www8TRAAAAYkwEoCqqqo0fPhwHThwQJJ0zTXX6I477jBcFQAADUMYCUCPPvqo1q1bJ0lKSkrSSy+9xCW7AICARRgJMGvXrtWjjz4qSQoNDdVrr72m1q1bG64KAICGI4wEkH379mn48OFyuVySpBkzZujCCy80XBUAACeHMBIgLMvS6NGj9eOPP0qS/vjHP2rKlCmGqwIA4OQRRgKEZVk6//zzFRISojZt2ujVV19VaGio6bIAADhprDMSIEJCQvTggw/qoosuUkVFhdq1a2e6JAAAGgVhJMCkpaWZ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WeKrEpuNhhzryspK64ILLrBefPFFa9SoUYSRevD2OM+fP98644wzLKfT6a8SmwVvj/PEiROtSy65xGNbZmamNWDAAJ/W2ZzUJ4zcd9991plnnumxbejQodaQIUN8VlezHaZxOp3KyclRenq6e1tISIjS09OVnZ1da5vs7GyP/SVpyJAhx90fDTvOxyorK1NFRYVat27tqzKbhYYe60ceeUQJCQm6+eab/VFmwGvIcX7//feVmpqqiRMnKjExUb169dLMmTNVVVXlr7IDTkOO8wUXXKCcnBz3UE5+fr5WrlypK664wi81BwsT58KAuFFeQ+zfv19VVVVKTEz02J6YmKht27bV2qagoKDW/QsKCnxWZ6BryHE+1v3336/27dvX+OOHp4Yc6w0bNmjx4sXKzc31Q4XNQ0OOc35+vtasWaPhw4dr5cqV2rlzp2677TZVVFRo+vTp/ig74DTkOA8bNkz79+/XhRdeKMuyVFlZqQkTJugvf/mLP0oOGsc7FzocDh0+fFiRkZGN/pnNtmcEgeGJJ57QsmXL9O6776pFixamy2lWSkpKNGLECC1atEjx8fGmy2nWXC6XEhIStHDhQvXv319Dhw7VtGnTtGDBAtOlNStr167VzJkz9fzzz2vz5s165513tGLFCj366KOmS8NJarY9I/Hx8QoNDVVhYaHH9sLCQrVt27bWNm3btvVqfzTsOFd7+umn9cQTT+ijjz5Snz59fFlms+Dtsf7222/13XffKSMjw73N5XJJksLCwrR9+3Z16dLFt0UHoIb8Tbdr107h4eEKDQ11b+vRo4cKCgrkdDoVERHh05oDUUOO84MPPqgRI0bolltukST17t1bpaWlGjdunKZNm6aQEP593RiOdy6Mjo72Sa+I1Ix7RiIiItS/f39lZWW5t7lcLmVlZSk1NbXWNqmpqR77S9Lq1auPuz8adpwl6amnntKjjz6qVatW6ZxzzvFHqQHP22OdnJysrVu3Kjc31/24+uqrNWjQIOXm5iopKcmf5QeMhvxNDxgwQDt37nSHPUnasWOH2rVrRxA5joYc57KyshqBozoAWtxmrdEYORf6bGpsE7Bs2TLLbrdbr7zyivX1119b48aNs2JjY62CggLLsixrxIgR1pQpU9z7f/rpp1ZYWJj19NNPW3l5edb06dO5tLcevD3OTzzxhBUREWG99dZb1k8//eR+lJSUmPoKAcPbY30srqapH2+P8+7du62oqCjr9ttvt7Zv327985//tBISEqzHHnvM1FcICN4e5+nTp1tRUVHW66+/buXn51sffvih1aVLF+v666839RUCQklJibVlyxZry5YtliRr9uzZ1pYtW6zvv//esizLmjJlijVixAj3/tWX9t57771WXl6eNW/ePC7tPVnPPfecddppp1kRERHWeeedZ3322Wfu31100UXWqFGjPPZ/4403rG7dulkRERHWmWeeaa1YscLPFQcmb45zp06dLEk1HtOnT/d/4QHI27/poxFG6s/b47xx40YrJSXFstvt1hlnnGE9/vjjVmVlpZ+rDjzeHOeKigrr4Ycftrp06WK1aNHCSkpKsm677Tbr4MGD/i88gHz88ce1/j+3+tiOGjXKuuiii2q06devnxUREWGdccYZ1ssvv+zTGm2WRd8WAAAwp9nOGQEAAIGBMAIAAIwijAAAAKMIIwAAwCjCCAAAMIowAgAAjCKMAAAAowgjAADAKMIIAAAwijACAACMIowAAACjCCMAAMCo/wewP/2uHjsYCQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import roc_curve, auc\n",
    "roc_auc = auc(fpr,tpr)   # 准确率代表所有正确的占所有数据的比值\n",
    "plt.plot(fpr, tpr, 'k--', label='ROC (area = {0:.2f})'.format(roc_auc), lw=2)\n",
    "plt.savefig(\"旋转2的roc.png\",dpi=600)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "77ba3849-774b-4293-9ccb-ceedc7e13412",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-01-07T07:56:45.397957Z",
     "iopub.status.busy": "2024-01-07T07:56:45.396376Z",
     "iopub.status.idle": "2024-01-07T07:56:45.709827Z",
     "shell.execute_reply": "2024-01-07T07:56:45.708699Z",
     "shell.execute_reply.started": "2024-01-07T07:56:45.397865Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f8140027160>"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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c+bkPc+DiQiWLVuGJ554Ahs3bsSUKVPils+aNQsOhyOujLt370ZLS0tcGbdv3x53ga1fvx7l5eVDbr5GoGkaAoGAJcp2zjnnYPv27Whubo6m2bNnY9GiRdF/m72Msbq7u/Hhhx9i/Pjxljh+X/ziF4cM63///fcxefJkANa4xwx46KGHUFNTgwULFkRfs8Ix7O3tharGP5ZtNhs0TQNgrWOYEr176aZrzZo14nK5ZPXq1fLuu+/KD37wA6moqIjrlW1UXV1d8tZbb8lbb70lAOSXv/ylvPXWW/Lxxx+LSP/wsYqKCvnrX/8q77zzjpx//vkJh4997nOfk82bN8srr7wiJ510kmGGj1111VXidrvlxRdfjBsK2NvbG11nyZIl0tDQIBs3bpStW7eKx+MRj8cTXT4wDHDu3LnS3Nws69atk+rqakMMA1y+fLls2rRJ9u7dK++8844sX75cFEWRf/zjHyJi7rINJ3YUj4i5y3jDDTfIiy++KHv37pVXX31VGhsbpaqqSjo6OkTE3GUT6R8abrfb5fbbb5c9e/bIo48+KiUlJfLII49E1zH7PUakf+RmQ0OD3HTTTUOWmf0YLl68WCZMmBAdZvz4449LVVWV/OhHP4quY4VjmCrTBSgiIvfdd580NDSI0+mUM888U15//XW9s5SSF154QQAMSYsXLxaR/iFkP/3pT6W2tlZcLpecc845snv37rhtHDp0SL797W9LaWmplJeXy2WXXSZdXV06lGaoRGUDIA899FB0nb6+Prn66qulsrJSSkpK5MILL5T9+/fHbWffvn0yf/58KS4ulqqqKrnhhhskFArluTRDXX755TJ58mRxOp1SXV0t55xzTjQ4ETF32YYzOEAxcxkvvvhiGT9+vDidTpkwYYJcfPHFcXOEmLlsA55++mmZPn26uFwumTp1qvzud7+LW272e4yIyN///ncBMCTfIuY/hj6fT6655hppaGiQoqIiOf744+UnP/lJ3BBoKxzDVCkiMVPUERERERmAqfqgEBERUWFggEJERESGwwCFiIiIDIcBChERERkOAxQiIiIyHAYoREREZDgMUIiIiMhwGKAQERGR4TBAISIiIsNhgEJERESGwwCFiIiIDOf/B/Mu3MzUjJOkAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "img = cv2.imread(\"../data/Image Set 200/greenland_250.jpg\")\n",
    "center = (100,100)\n",
    "outer_radius = 70\n",
    "inner_radius = 60\n",
    "mask = np.ones((589, 883, 3), np.uint8)*1\n",
    "cv2.circle(mask, center, int(outer_radius), (255, 255, 255), thickness=-1, lineType=7) # 使得mask中outer_rasius内部的值为255\n",
    "cv2.circle(mask, center, int(inner_radius), (0, 0, 0), thickness=-1, lineType=cv2.LINE_AA)# 使得mask中inner_radius内部的值为0，从而实现环形的目的\n",
    "img_process = cv2.bitwise_and(img, mask)\n",
    "plt.imshow(img_process)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "945dcc01-f038-46bc-86d3-2cc17dea0689",
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-01-27T13:39:43.683870Z",
     "iopub.status.idle": "2024-01-27T13:39:43.683870Z",
     "shell.execute_reply": "2024-01-27T13:39:43.683870Z",
     "shell.execute_reply.started": "2024-01-27T13:39:43.683870Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "\"abc\".find(bc)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "image",
   "language": "python",
   "name": "image"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
